﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using SmallERP.MODEL.FoundationModel;
using System.Text.RegularExpressions;
using System.Configuration;
using System.Windows.Forms;
using System.Diagnostics;

namespace SmallERP.COM
{
    /// <summary>
    /// 登陆进行连接字符串比较或是获取需要的信息
    /// </summary>
    public class StartUPUtil
    {
        public StartUPUtil()
        {
            Application.ApplicationExit += new EventHandler(Restart);
        }
        private const int TCPPORT = 8001;//TCP发送信息的默认端口号

        private static Socket CreateSendMsgSocket()
        {
            //得到本机IP，设置TCP端口号         
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, TCPPORT);
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            newsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
            //绑定网络地址
            newsock.Bind(ipep);
            return newsock;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serverInfo"></param>
        /// <returns>-5:未见有服务器启动</returns>
        private int GetServerInfo(out List<string> list)
        {
            int result = 0;
            int recv = 0;
            byte[] data = new byte[1024];
            list = new List<string>();

            //Socket newsock = CreateSendMsgSocket();
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, TCPPORT);
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            newsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
            //绑定网络地址
            newsock.Bind(ipep);
   
            //得到客户机IP
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint Remote = (EndPoint)(sender);
            string strTemp = string.Empty;
            DateTime nowTime = DateTime.Now;
            try
            {
                while (((TimeSpan)(DateTime.Now - nowTime)).Seconds < 4)
                {
                    try
                    {
                        recv = newsock.ReceiveFrom(data, ref Remote);
                    }
                    catch
                    {
                        //MessageBox.Show("未见有服务器启动,请与管理员联系", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        result = -5;
                        newsock.Close();
                    }            

                    string strData = Encoding.Unicode.GetString(data, 0, recv);

                    strTemp = list.Find(delegate(string a)
                    {
                        if (a.Equals(strData))
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }

                    });
                    if (strTemp == null)
                    {
                        list.Add(strData);
                    }
                }       //cmbServer.Text = "服务器已刷新,请下拉选择:";   
            }
            catch (Exception)
            {

                result = -5;
            }
            finally
            {
                newsock.Close();
            }
            return result;
            //return list;
        }

        /// <summary>
        /// 将字符串转变为SERVERINFO类
        /// </summary>
        /// <param name="serverInfo"></param>
        /// <returns>0:正确,-1:服务信息不全,-2:服务设置IP格式不正确,-3:服务设置端口号格式不正确,-4:解析出错</returns>
        private int ConvertServerInfo(List<string> serverInfoList, out ServerInfo serverInfo)
        {
            serverInfo = new ServerInfo();
            //string strConn = string.Empty;//连接字符
            //string strAlarmInfo = string.Empty;
            //string strIP = string.Empty;
            //string strPort = string.Empty;
            try
            {
                if (serverInfoList.FirstOrDefault().Split('|').Length < 4)
                {
                    return -1;
                }
                serverInfo.SqlConn = serverInfoList.FirstOrDefault().Split('|')[0];
                serverInfo.AlarmMsg = serverInfoList.FirstOrDefault().Split('|')[1];
                serverInfo.ServerIP = serverInfoList.FirstOrDefault().Split('|')[2];
                serverInfo.ServerTCPPort = Convert.ToInt32(serverInfoList.FirstOrDefault().Split('|')[3]);

                bool ipCheck = Regex.IsMatch(serverInfo.ServerIP, @"^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$", RegexOptions.IgnoreCase);


                if (!ipCheck)
                {
                    return -2;
                    //MessageBox.Show("服务设置IP格式不正确", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    //Application.Exit();
                }
                bool portCheck = Regex.IsMatch(serverInfo.ServerTCPPort.ToString(), @"^\d+$");
                if (!portCheck)
                {
                    return -3;
                    //MessageBox.Show("服务设置端口号格式不正确", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    //Application.Exit();
                }
            }
            catch (Exception exception)
            {
                return -4;
                //MessageBox.Show(exception.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                //Application.Exit();
            }
            return 0;
        }
        public string GetIpAdress()
        {
            List<string> resource = new List<string>();
            GetServerInfo(out resource);
            if (resource.Count > 0)
            {
                return resource.FirstOrDefault();
            }
            else
            {
                return "";
            }
        }
        /// <summary>
        /// 得到服务器的相关信息
        /// </summary>
        /// <param name="serverInfo"></param>
        /// <returns>0:正确,-1:服务信息不全,-2:服务设置IP格式不正确,-3:服务设置端口号格式不正确,-4:解析出错,-5:未见有服务器启动,-6:需要重启</returns>
        public int GetServerInfo(out ServerInfo serverInfo, out string errMsg)
        {
            int result = 0;
            errMsg = string.Empty;
            serverInfo = new ServerInfo();
            List<string> resource = new List<string>();
            result = GetServerInfo(out resource);
            if (result == 0)
            {
                result = ConvertServerInfo(resource, out serverInfo);
                if (result == 0)
                {
                    if (CheckConfig(serverInfo))
                        result = -6;
                }
            }

            errMsg = AnalyseErrCode(result);
            return result;
        }

        /// <summary>
        /// 分板结果返回错误信息
        /// </summary>
        /// <param name="errCode"></param>
        /// <returns></returns>
        private string AnalyseErrCode(int errCode)
        {
            string strErr = string.Empty;
            switch (errCode)
            {
                case -1: strErr = "服务信息不全,请检查服务器设置";
                    break;
                case -2: strErr = "服务设置IP格式不正确";
                    break;
                case -3: strErr = "服务设置端口号格式不正确";
                    break;
                case -4: strErr = "解析出错";
                    break;
                case -5: strErr = "未见有服务器启动";
                    break;
                case -6: strErr = "服务器地址改变，程序将重启";
                    //isNeedRestart = true;
                    break;
            }
            return strErr;
        }

        /// <summary>
        /// 检查连接字符串是否有修改
        /// </summary>
        /// <param name="serverInfo"></param>
        /// <returns>是否需要重启</returns>
        private bool CheckConfig(ServerInfo serverInfo)
        {
            //现在的连接字符串
            string connectionString = ConfigurationManager.ConnectionStrings[1].ToString();


            string strConnServer = serverInfo.SqlConn + ";";
            string strConnEnd = string.Empty;

            strConnEnd = connectionString.Substring(connectionString.IndexOf("MultipleActiveResultSets"));
            string strConnHead = connectionString.Substring(0, connectionString.IndexOf("Data Source"));

            //由服务器发出来的连接字符串组成的新的
            string connectionString_Server = strConnHead + strConnServer + strConnEnd;
            //ConnectionStringSettings mySettings = new ConnectionStringSettings("smallerpDataContext", connectionString, "System.Data.EntityClient");

            if (connectionString_Server.ToString().Equals(connectionString))
            {
                _serverChange = false;
                return false;
            }
            else
            {
                System.Configuration.Configuration config =
                    ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                config.ConnectionStrings.ConnectionStrings.Remove("smallerpDataContext");
                ConnectionStringSettings mySettings = new ConnectionStringSettings("smallerpDataContext", connectionString_Server, "System.Data.EntityClient");
                config.ConnectionStrings.ConnectionStrings.Add(mySettings);
                config.Save(ConfigurationSaveMode.Minimal);
                ConfigurationManager.RefreshSection("ConnectionStrings");
                _serverChange = true;
                Application.Exit();
                return true;
            }
        }
        bool _serverChange = false;
        //默认重启
        private void Restart(object sender, EventArgs e)
        {

            if (_serverChange)
            {
                Process.Start(Application.ExecutablePath);
            }
        }

    }
}
